package libce

import (
	"sync"
	"time"

	cache "github.com/patrickmn/go-cache"
)

type (
	MemoryCache struct {
		cache.Cache
	}
)

func (ce *MemoryCache) Client() cache.Cache {
	return ce.Cache
}

func (ce *MemoryCache) RememberWarp(rememberFunc RememberFunc, op RememberOption) RememberFunc {
	return func() (value interface{}, err error) {
		val, has := ce.Get(op.Key)
		if has {
			value = val
			return
		}
		if value, err = rememberFunc(); err != nil {
			return
		}
		if op.Expire <= 0 {
			op.Expire = cache.NoExpiration
		}
		ce.Set(op.Key, value, op.Expire)
		return
	}
}

var (
	memoryCache *MemoryCache
	chMu        = new(sync.Mutex)
)

func NewMemoryCache() *MemoryCache {
	chMu.Lock()
	defer chMu.Unlock()
	if memoryCache == nil {
		ce := cache.New(time.Minute*5, time.Minute*10)
		memoryCache = &MemoryCache{Cache: *ce}
	}
	return memoryCache
}
